/**************************************************************************
Date: 协议结构
Description: 协议集成结构
**************************************************************************/

#ifndef CCMD_BASE_H_
#define CCMD_BASE_H_

#include <QDebug>
#include "CXJson.h"
#include "xpack/xpack.h"
#include "CNetworkServiceHeader.h"

/*
  空的数据结构，用于编码时需要空的{}
*/
typedef struct _tNullData{
    XJSON_FUNCI
	string nullStr;
	_tNullData()
	{
		nullStr = "";
	}
    XPACK(X(F(OE),nullStr));
}T_NullData;


// 命令格式信息
typedef struct _tCmdBaseData{
    XJSON_FUNCI

	// 命令
    string cmd;
    // 发起方sn
    string	sn;
    // 发起方消息ID：http访问包含在头中
    string	sendMsgId;
    // 协议号回复请求消息ID:http为同步接口不需要包含此字段
    string	recvMsgId;
	// 设备当前秒时间戳
	uint64_t timestamp;
	// 鉴权签名：MD5(MD5(msgId + timestamp(转为字符串)))
    string signature;
    // 鉴权key：通讯鉴权信息，http访问包含在头中
    string	appKey;
    int code;
    // 返回消息
    string msg;
	_tCmdBaseData(){
		cmd = "";
        sn = "";
        sendMsgId = "";
		signature = "";
        msg = "";
        appKey = "";
		timestamp = 0;
		code = 200;
	}
    XPACK(X(F(OE), cmd, recvMsgId, sendMsgId, timestamp, signature, code, msg, appKey, sn));
}T_CmdBaseData;

template <class T>
struct tCmdData: public T_CmdBaseData{
    XJSON_FUNCI

	T data;

	tCmdData()
	{
		clear();
	}

	tCmdData(T p)
	:data(p)
	{
		clear();
	}

	bool operator=(T p){
		data = p;
		return true;
	}
    bool operator=(const T_CmdBaseData & p){
        cmd = p.cmd;
        recvMsgId = p.recvMsgId;
        timestamp = p.timestamp;
        signature = p.signature;
        msg = p.msg;
        code = p.code;
        sendMsgId = p.sendMsgId;
        sn = p.sn;
        return true;
    }

	void clear()
	{
		cmd = "";
        recvMsgId = "";
        sendMsgId = "";
		timestamp = 0;
		signature = "";
        msg = "";
        sn = "";
		code = 200;
	}

	void reset()
	{
        cmd = "";
        sn = "";
        recvMsgId = "";
        sendMsgId = "";
		timestamp = 0;
		signature = "";
        msg = "";
		code = 200;
	}
	XPACK(X(F(OE),data),I(T_CmdBaseData));
};

// 数据来源
typedef enum _eRouteType{
    ROUTE_NONE = -1,
    ROUTE_HTTP_CLIENT = 1,	// HTTP请求本设备的数据
    ROUTE_HTTP_SERVICE,		// HTTP请求服务器返回的数据
    ROUTE_MQTT_SERVICE,		// MQTT客户端
    ROUTE_UDP_CLIENT,		// UDP请求本设备的数据
    ROUTE_DUP_SERVICE,		// UDP请求服务器返回的数据
}E_RouteType;


typedef enum _eNetDevRunMode{
    NET_DEV_RUN_NULL = 0,	//不请求
    NET_DEV_RUN_HTTP,		//HTTP请求
    NET_DEV_RUN_MQTT,		//MQTT请求
    NET_DEV_RUN_UDP,		// UDP
}E_NetDevRunMode;


typedef struct _tHttpClientReqInfo{
    XJSON_FUNCI
    // 请求方式
    tsHttpMethod method;
    // 请求地址
    string 		url;
    // 连接超时
    int			conTimeout;
    // 接收超时
    int			recvTimeout;
    _tHttpClientReqInfo(){
        url = "";
        method = GET;
        conTimeout = 3;
        recvTimeout = 10;
    }
    void clear(){
        url = "";
        method = GET;
        conTimeout = 3;
        recvTimeout = 10;
    }
    XPACK( O(method,url,conTimeout, recvTimeout));

}T_HttpClientReqInfo;

/*
消息路由
*/
struct tRoute{
    XJSON_FUNCI
    E_RouteType type;
    // udp发送IP
    string		udpIp;
    // udp发送端口
    int port;
    // http连接ID
    unsigned long httpId;
    // http请求信息
    T_HttpClientReqInfo httpClientInfo;
    // mqtt主题
    string		mqttTopics;
    // http请求地址
    string httpUrl;

    // 授权是否通过
    bool 		isAuthorizationSuccess;
    tRoute(){
        type = ROUTE_NONE;
        port = 0;
        udpIp = "";
        httpUrl = "";
        isAuthorizationSuccess = false;
    }

    void clear(){

        type = ROUTE_NONE;
        port = 0;
        httpId = 0;
        udpIp = "";
        httpUrl = "";
        isAuthorizationSuccess = false;
        httpClientInfo.clear();
    }
    XPACK( O(type, port, isAuthorizationSuccess, udpIp, httpClientInfo, mqttTopics));
};

/*
  路由数据
*/
template <class T>
struct tRouteData{
    XJSON_FUNCI
	struct tRoute route;
	struct tCmdData<T> msg;

	tRouteData() = default;
	tRouteData( T p)
	:msg(p)
	{

	}
	bool operator=(struct tRouteData<string> &p){
		route = p.route;
        msg = p.msg;
		return true;
	}
	bool operator=(T p){
		msg = p;
		return true;
	}
	void clear(){
		route.clear();
		msg.clear();
	}
	XPACK( O(route,msg));
};

// 请求成功
#define NET_CODE_OK   200
// 部分内容成功
#define NET_CODE_PART_OK   201
// 鉴权错误
#define NET_CODE_SIGNATURE_FIAL  300
// 请求失败
#define NET_CODE_FAIL   301
// 请求内容错误
#define NET_CODE_DATA_FAIL   302

#endif // CCMD_BASE_H_
